--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_komeiji_koishi = General:new(extension, "hy_komeiji_koishi", "chi_k", 3, 3, General.Female)
    local egoless = fk.CreateSkill {
        name = "egoless",
    }
    egoless:addEffect(fk.EventPhaseStart, {
        anim_type = "support",
        can_trigger = function(self, event, target, player)
            return player:hasSkill(egoless.name) and player.phase == Player.Discard and #table.filter(player.player_cards[Player.Hand], function(id)
                return not player:prohibitDiscard(Fk:getCardById(id))
            end) > 0
        end,
        on_cost = function(self, event, target, player, data)
            return player.room:askToSkillInvoke(player, {
                skill_name = egoless.name,
                prompt = "egoless_prompt"
            })
        end,
        on_use = function(self, event, target, player)
            local room = player.room
            local suits = {}
            local cards = table.filter(player:getCardIds("h"), function(id)
                return not player:prohibitDiscard(Fk:getCardById(id))
            end)
            for _, id in ipairs(cards) do
                table.insertIfNeed(suits, Fk:getCardById(id):getSuitString(true))
            end
            room:throwCard(cards, egoless.name, player, player)
            local targets = room:askToChoosePlayers(player, {
                targets = room:getOtherPlayers(player),
                min_num = 1,
                max_num = 1,
                skill_name = egoless.name,
                prompt = "egoless_prompt_target",
            })
            if #targets == 0 then
                return
            end
            local suit
            if #suits > 1 then
                local listNames = { "log_spade", "log_club", "log_heart", "log_diamond" }
                local listCards = { {}, {}, {}, {} }
                for _, id in ipairs(cards) do
                    local suit = Fk:getCardById(id).suit
                    if suit ~= Card.NoSuit then
                        table.insertIfNeed(listCards[suit], id)
                    end
                end
                suit = U.askForChooseCardList(room, player, listNames, listCards, 1, 1, egoless.name, "egoless_prompt_choose::" .. targets[1].id)[1]
            else
                suit = suits[1]
            end
            local gives = table.filter(cards, function(id)
                return Fk:getCardById(id):getSuitString(true) == suit
            end)
            if #suits == 1 then
                room:delay(700)
            end
            room:moveCards({
                ids = gives,
                toArea = Card.PlayerHand,
                to = targets[1],
                moveReason = fk.ReasonGive,
                proposer = player,
                skillName = egoless.name,
            })
        end,
    })
    egoless:addEffect(fk.AfterCardsMove, {
        can_refresh = function(self, event, target, player, data)
            return player:hasSkill(egoless.name) and table.any(data, function(move)
                return move.from == player and table.any(move.moveInfo, function(info)
                    return info.fromArea == Card.PlayerHand
                end)
            end)
        end,
        on_refresh = function(self, event, target, player, data)
            local room = player.room
            local value = player:getMark("@egoless") or 0
            for _, move in ipairs(data) do
                if move.from == player then
                    value = value + #table.filter(move.moveInfo, function(info)
                        return info.fromArea == Card.PlayerHand
                    end)
                end
            end
            value = math.min(value, 4)
            room:setPlayerMark(player, "@egoless", value)
        end,
    })
    egoless:addEffect(fk.EventPhaseStart, {
        can_refresh = function(self, event, target, player, data)
            return player:hasSkill(egoless.name) and player == target and target.phase == Player.Play
        end,
        on_refresh = function(self, event, target, player, data)
            local room = player.room
            room:setPlayerMark(player, "@egoless", 0)
        end,
    })
    egoless:addEffect(fk.AskForCardUse, {
        anim_type = "defensive",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(egoless.name) and player:getMark("@egoless") > 0 and target == player and data.pattern ~= "nullification" and Fk:currentRoom().current ~= player
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local card_count = player:getMark("@egoless")
            local cardIds = room:getNCards(card_count)
            local valid_cardIds = table.filter(cardIds, function(id, _, _)
                return Exppattern:Parse(data.pattern):match(Fk:getCardById(id))
            end)
            HY.ReplaceHandCardToTempNew(player, cardIds)
            local cardId = HY.AskForCard(player, 1, 1, false, egoless.name, #valid_cardIds == 0, ".|.|.|.|.|.|" .. table.concat(valid_cardIds, ","))
            HY.ReverseHandCardFromTempNew(player)
            if #cardId > 0 then
                data.result = {
                    from = player,
                    card = Fk:getCardById(cardId[1]),
                }
                table.insertIfNeed(data.result.card.skillNames, egoless.name)

                if data.eventData then
                    if data.eventData.card.name == "collateral" then
                        data.result.tos = { data.extraData.must_targets }
                    end
                    data.result.toCard = data.eventData.toCard
                    data.result.responseToEvent = data.eventData.responseToEvent
                end
                table.removeOne(cardIds, cardId[1])
                if data.pattern == "jink" and data.result then
                    return true
                end
            end
        end,

    })
    egoless:addEffect(fk.AskForCardResponse, {
        anim_type = "defensive",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(egoless.name) and player:getMark("@egoless") > 0 and target == player and data.pattern ~= "nullification" and Fk:currentRoom().current ~= player
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local card_count = player:getMark("@egoless")
            local cardIds = room:getNCards(card_count)
            local valid_cardIds = table.filter(cardIds, function(id, _, _)
                return Exppattern:Parse(data.pattern):match(Fk:getCardById(id))
            end)
            HY.ReplaceHandCardToTempNew(player, cardIds)
            local cardId = HY.AskForCard(player, 1, 1, false, egoless.name, #valid_cardIds == 0, ".|.|.|.|.|.|" .. table.concat(valid_cardIds, ","))
            HY.ReverseHandCardFromTempNew(player)
            if #cardId > 0 then
                data.result = Fk:getCardById(cardId[1])
                data.result.skillName = egoless.name
                table.removeOne(cardIds, cardId[1])
                if data.pattern == "jink" and data.result then
                    return true
                end
            end
        end,
    })
    local cursed_ring = fk.CreateSkill {
        name = "cursed_ring",
    }
    cursed_ring:addEffect(fk.EventPhaseStart, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(cursed_ring.name) and player == target and player.phase == Player.Draw and player:canUse(Fk:cloneCard("thunder__slash"))
        end,
        on_cost = function(self, event, target, player)
            local room = player.room
            local targets = table.filter(room.alive_players, function(target, _, _)
                return target ~= player and not player:isProhibited(target, Fk:cloneCard("thunder__slash"))
            end)
            local result = room:askToChoosePlayers(player, {
                targets = targets,
                min_num = 1,
                max_num = 1,
                skill_name = cursed_ring.name,
                prompt = "cursed_ring_prompt"
            })
            if #result > 0 then
                event:setCostData(self, result)
                return true
            end
        end,
        on_use = function(self, event, target, player)
            local room = player.room
            room:broadcastPlaySound("./packages/touhou_hy/audio/skill/cursed_ring2_hidden")
            local card = Fk:cloneCard("thunder__slash")
            table.insertIfNeed(card.skillNames, cursed_ring.name)
            room:useCard({
                from = player,
                tos = event:getCostData(self),
                card = card,
                extraUse = true,
            })
        end,
    })
    cursed_ring:addEffect(fk.CardUseFinished, {
        anim_type = "offensive",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(cursed_ring.name) and data.card and table.contains(data.card.skillNames, "cursed_ring") and data.damageDealt and table.any(data.damageDealt, function(value)
                return value > 0
            end) and #data.tos >= 1 and not player.dead
        end,
        on_cost = function(self, event, target, player, data)
            return true
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            room:broadcastPlaySound("./packages/touhou_hy/audio/skill/cursed_ring1_hidden")
            room:drawCards(player, 2, cursed_ring.name)
        end,
    })
    extension:loadSkillSkels { egoless, cursed_ring }
    hy_komeiji_koishi:addSkills { "egoless", "cursed_ring" }
    Fk:loadTranslationTable {
        ["hy_komeiji_koishi"] = "古明地恋",
        ["#hy_komeiji_koishi"] = "飘渺游行",
        ["illustrator:hy_komeiji_koishi"] = "たみく",
        ["designer:hy_komeiji_koishi"] = "黑曜人形",
        ["cv:hy_komeiji_koishi"] = "",

        ["egoless"] = "无我",
        [":egoless"] = "弃牌阶段开始时，你可以弃置所有手牌，然后可以令一名其他角色获得其中一种花色的所有牌。当你于回合外需要使用或打出基本牌时，你可以观看牌堆顶X张牌，然后使用或打出其中一张你需要的牌（X为直到你的上个出牌阶段开始为止你失去的手牌数且至多为4）。",
        ["@egoless"] = "无我",
        ["egoless_prompt"] = "无我：你可以弃置所有手牌",
        ["egoless_prompt_target"] = "无我：你可以令一名角色获得一种花色的牌",
        ["egoless_prompt_choose"] = "无我：将一种花色的手牌交给%dest",

        ["cursed_ring"] = "咒铃",
        [":cursed_ring"] = "摸牌阶段开始时，你可以视为对一名角色使用无距离限制的雷【杀】，若此【杀】造成了伤害，摸两张牌。",
        ["cursed_ring_prompt"] = "咒铃：你可以视为使用一张无距离限制的雷【杀】",
    }
end
